﻿using UnityEngine;
using System.Collections;
using TTGameEngine;
using System;
using System.Collections.Generic;
using System.Reflection;
using TTUnityPlugin;

namespace TTGame
{

    public delegate void SetFunc<T>(T b);
    public delegate T GetFunc<T>();

    public interface IInspectorPropHandler
    {
        void RefreshValue();
        void TriggerSet();
    }

    public class InspectorPropHandler<T> : IInspectorPropHandler
    {
        T value = default(T);
        public SetFunc<T> setFunc;
        public GetFunc<T> getFunc;

        public InspectorPropHandler(SetFunc<T> aSetFunc, GetFunc<T> aGetFunc)
        {
            setFunc = aSetFunc;
            getFunc = aGetFunc;
            value = getFunc();
        }

        /// <summary>
        /// 检查对应属性的Value，如果和保存的Value不一样的话，调用Set方法重新赋值。
        /// </summary>
        public void RefreshValue()
        {
            T newValue = getFunc();
            if (value.Equals(newValue) == false)
            {
                setFunc(newValue);
                value = newValue;
            }
        }

        public void TriggerSet()
        {
            setFunc(value);
        }
    }
    public class DebugSetting : MonoBehaviour
    {
        static public DebugSetting m_ins = null;

        static public DebugSetting Self
        {
            get
            {
                if (m_ins == null)
                {
                    DebugUtil.LogFormat("m_ins");
                    m_ins = GameLauncher.Self.AddLogicScript<DebugSetting>();
                }
                return m_ins;
            }
        }

        #region Log开关
        public bool m_logEnable = false;
        public bool m_puppetAILog = false;
        public bool m_puppetLog = false;
        public bool m_skillSysLog = false;
        public bool m_animLog = false;
        public bool m_magicBallLog = false;
        public bool m_isDrawColliderWire = false;
        public bool m_cutSceneLogFlag = false;
        public bool m_netLog = false;
        public bool m_NetResponeLog = false;
        #endregion


        public bool ShowMessageLog = false;
        public string LimitObjName = "";

        public bool Debug_LocalScene = false;
        public bool HeroFullAnger = false;
        //----------碰撞排斥------------
        [Tooltip("开启碰撞排斥")]
        public bool IsColliderMove = true;
        [Tooltip("碰撞时，平滑的旋转速度。单位：角度/s")]
        public int ColliderRotationSpeed = 360;
        [Tooltip("碰撞排斥的程度"), Range(0, 0.99f)]
        public float ColliderMoveFactor = 0.98f;
        [Tooltip("使用CharacterController控件来移动")]
        public bool moveUsingCharacterController = false;
        //---------预加载设置-----------
        [Tooltip("每帧提供一点点时间用于加载，可根据FPS确定每帧要提供的加载时间，10FPS=0.1s。最慢也是每帧加载一个对象")]
        public float LoadFPSTimeLimit = 0.2f;
        //状态提前结束，为了给下一个状态动画过渡留出时间。
        public float m_StateLimitTimeFactor = 1f;
        public int SkillDamageType = -1;
        public float FastTime = 1f;

        string[] BoolFuncNames = {
        "Debug_logEnable",
        "Debug_puppetAILog",
        "Debug_puppetLog",
        "Debug_skillSysLog",
        "Debug_animLog",
        "Debug_magicBallLog",
        "Debug_isDrawColliderWire",
        "Debug_cutSceneLogFlag"
    };
        string[] FloatFuncNames = {
        "Debug_StateLimitTimeFactor"
    };

        public Dictionary<string, Action<bool>> Flags = new Dictionary<string, Action<bool>>();

        List<IInspectorPropHandler> ValueEvent = new List<IInspectorPropHandler>();
        List<bool> lastValue = new List<bool>();

        public bool Debug_logEnable
        {
            set
            {
                m_logEnable = value;
                DebugUtil.debugLevel = m_logEnable ? DEBUGLEVEL.DEBUG : DEBUGLEVEL.NOLOG;
                //PluginLog.OpenLog = m_logEnable;
            }
            get { return m_logEnable; }
        }


        public bool Debug_puppetAILog
        {
            set
            {
                m_puppetLog = value;
                Puppet.PuppetLogFlag = m_puppetLog;
            }
            get { return m_puppetLog; }
        }
        public bool Debug_puppetLog
        {
            set
            {
                m_puppetAILog = value;
                PuppetAI.PuppetAILogFlag = m_puppetAILog;
            }
            get { return m_puppetAILog; }
        }

        public bool Debug_skillSysLog
        {
            set
            {
                m_skillSysLog = value;
                SkillTimelineSystem.SkillSystemLogFlag = m_skillSysLog;
            }
            get { return m_skillSysLog; }
        }

        public bool Debug_animLog
        {
            set
            {
                m_animLog = value;
                AnimPlayer.AnimPlayerLogFlag = m_animLog;
            }
            get { return m_animLog; }
        }

        public bool Debug_magicBallLog
        {
            set
            {
                m_magicBallLog = value;
                MagicBall.MagicBallLogFlag = m_magicBallLog;
            }
            get { return m_magicBallLog; }
        }

        public bool Debug_isDrawColliderWire
        {
            set
            {
                m_isDrawColliderWire = value;
                DamageReceiverCollider.IsDrawColliderWire = m_isDrawColliderWire;
            }
            get { return m_isDrawColliderWire; }
        }

        public bool Debug_cutSceneLogFlag
        {
            set
            {
                m_cutSceneLogFlag = value;
                CinemaDirector.Cutscene.CutsceneLogFlag = m_cutSceneLogFlag;
            }
            get { return m_cutSceneLogFlag; }
        }

        public float Debug_StateLimitTimeFactor
        {
            set
            {
                m_StateLimitTimeFactor = value;
                Puppet.StateEndingTimeFactor = m_StateLimitTimeFactor;
            }
            get { return m_StateLimitTimeFactor; }
        }

        public void Awake()
        {
            DebugUtil.LogFormat("Awake");
            if (m_ins != null)
            {
                enabled = false;
                DebugUtil.LogFormat("Destroy");
                Destroy(this);
                return;
            }
            m_ins = this;
#if !UNITY_EDITOR
        resetDefaultValues();
#endif
#if UNITY_EDITOR
            CollectEventHandler<bool>(BoolFuncNames);
            CollectEventHandler<float>(FloatFuncNames);
#endif

            if (ColliderMoveFactor >= 1) ColliderMoveFactor = 0.99f;
        }

        void CollectEventHandler<T>(string[] propNames)
        {
            for (int i = 0; i < propNames.Length; i++)
            {
                string propName = propNames[i];
                PropertyInfo prop = typeof(DebugSetting).GetProperty(propName);
                MethodInfo getMInfo = prop.GetGetMethod();
                MethodInfo setMInfo = prop.GetSetMethod();
                if (getMInfo != null && setMInfo != null)
                {
                    GetFunc<T> cb_getFunc = Delegate.CreateDelegate(typeof(GetFunc<T>), this, getMInfo) as GetFunc<T>;
                    SetFunc<T> cb_setFunc = Delegate.CreateDelegate(typeof(SetFunc<T>), this, setMInfo) as SetFunc<T>;
                    ValueEvent.Add(new InspectorPropHandler<T>(cb_setFunc, cb_getFunc));
                }
                else
                {
                    DebugUtil.LogErrorFormat("[DebugSetting] prop[{0}] no set/get Func!!!", propName);
                }
            }
        }

#if UNITY_EDITOR
        void OnEnable()
        {
            DebugUtil.LogFormat("OnEnable");
        }

        void OnDisable()
        {
            DebugUtil.LogFormat("OnDisable");
        }

        void Start()
        {
            //检查变量是否被编辑器面板修改
            for (int i = 0; i < ValueEvent.Count; i++)
            {
                ValueEvent[i].TriggerSet();
            }
        }

        void Update()
        {
            //检查变量是否被编辑器面板修改
            for (int i = 0; i < ValueEvent.Count; i++)
            {
                ValueEvent[i].RefreshValue();
            }

            if (FastTime > 0f && FastTime < 10f)
            {
                Time.timeScale = FastTime;
                if (FastTime == 1f) FastTime = 0;
            }
        }
#endif

        //正式环境，这些变量必须要重置。
        public void resetDefaultValues()
        {
            Debug_logEnable = false;
            Debug_puppetAILog = false;
            Debug_puppetLog = false;
            Debug_skillSysLog = false;
            Debug_animLog = false;
            Debug_magicBallLog = false;
            Debug_isDrawColliderWire = false;
            Debug_cutSceneLogFlag = false;
            ShowMessageLog = false;
            LimitObjName = "";
            Debug_LocalScene = false;
            HeroFullAnger = false;
            m_StateLimitTimeFactor = 1f;
            SkillDamageType = -1;
            FastTime = 1f;
            //         IsColliderMove = true;
            //         ColliderRotationSpeed = 360;
            //         ColliderMoveFactor = 0.98f;
            //         moveUsingCharacterController = false;
        }

    }
}